<template>
  <div v-loading="loading" class="fd-nav-content connector-setting-view-main">
    <section class="dingflow-design">
      <div class="zoom">
        <div
          :class="'zoom-out' + (nowVal == 50 ? ' disabled' : '')"
          @click="zoomSize(1)"
        ></div>
        <span>{{ nowVal }}%</span>
        <div
          :class="'zoom-in' + (nowVal == 300 ? ' disabled' : '')"
          @click="zoomSize(2)"
        ></div>
      </div>
      <div
        class="box-scale"
        id="box-scale"
        :style="
          'transform: scale(' +
            nowVal / 100 +
            '); transform-origin: 50% 0px 0px;'
        "
      >
        <nodeWrap
          :nodeConfig.sync="nodeConfig"
          :moduleListFrom="moduleListFrom"
          :moduleListTo="moduleListTo"
          :treeData.sync="nodeConfig"
          @startAppSelectChange="startAppSelectChangeHandler"
          @triggleActionSelectChange="triggleActionSelectChangeHandler"
          @executeApplicationSelectChange="onExecuteApplicationSelectChangeHandler"
        ></nodeWrap>
        <div class="end-node">
          <div class="end-node-circle"></div>
          <div class="end-node-text">{{ $t('common.connector.trigger.flowEnd') }}</div>
        </div>
      </div>
    </section>
  </div>
</template>
<script>
/* utils */
import { uuid } from 'pub-bbx-utils';
import { getNodeById, toServeData, toTreeData, validateTreeData, convertInsertFieldOptionsForServer, changeTreeNodeToServerNodeParams } from './utils/index';
import { message } from '@src/util/message'
/* api */
import * as triggerApi from '@src/modules/connector/api/trigger';
/* util */
import { findComponentDownward, findComponentsDownward } from '@src/util/assist';
import { flowStore } from '@src/modules/connector/view/setting/components/workflow/store'
import { cloneDeep } from '@src/util/type';
import { allowExecuteWay } from '@src/modules/connector/view/setting/common'
import { isArray } from '@src/util/type'

export default {
  name: 'connector-setting-view-main',
  data() {
    return {
      loading: false,
      nowVal: 100,
      nodeConfig: {},
      moduleListFrom: [],
      moduleListTo: [],
      id: '',
      serverTriggerInfo: {},
    };
  },
  provide(){
    let that = this;
    return {
      getParent(){
        return getNodeById(that.nodeConfig, this.parentId)
      },
      isCreateTrigger() {
        return this.isCreateTrigger
      }
    }
  },
  components: {},
  computed: {
    /**
     * @description 是否为新建触发器
    */
    isCreateTrigger() {
      return this.id.length == 0 && !this.getQueryString('bizTypeId')
    },
    isEditTrigger() {
      return !this.isCreateTrigger
    },
    sync() {
      return this.getQueryString('sync')
    },
  },
  created() {
    this.id = this.getQueryString('id') || ''
  },
  mounted() {
    const paramsFrom = {
      direction: 'from', // 起始节点全部改为from
    }
    const paramsTo = {
      direction: 'to', // 执行节点全部改为to
    }
    triggerApi.getAppList(paramsFrom).then(res => {

      if (res.status === 0) {
        this.moduleListFrom = res.data || [];
      }

      this.$nextTick(() => {
        this.openStartApplicationSelectForCreate()
      })

    });
    triggerApi.getAppList(paramsTo).then(res => {

      if (res.status === 0) {
        this.moduleListTo = res.data || [];
      }
    });
    if (this.id) {
      this.loading = true
      triggerApi.getTriggerDetailV2({triggerId: this.id}).then(async res=>{
        if(res.status === 0) {
          const triggerInfo = res?.data || {}
          const options = (isArray(res?.data.executeWay.options) ? res?.data.executeWay.options?.[0] : res?.data.executeWay.options) || {};
          flowStore.setTimerOptions(options)
          this.$emit('editInfo', { name: triggerInfo.name || '', description: triggerInfo.remarks || ''})

          const nodeList = triggerInfo?.nodeList || []
          const lineList = triggerInfo?.lineList || []

          let isToCustomer = false
          // 发起应用的apiId
          let fromApiId = '', toApiId = ''
          /**
           * @description 修改执行应用为客户时，联系人字段为文本框
           * @see http://zentao.shb.ltd/index.php?m=bug&f=view&bugID=21629&t=html&tid=45jsjnda
          */
          nodeList.forEach(node => {

            const isStart = node?.isStart
            if (isStart) {
              fromApiId = node.apiId
              return
            }

            toApiId = node?.apiId

          })

          // 获取条件设置的字段
          // const { data } = await triggerApi.getConditionConfig({fromApiId})
          const conditionFieldList = []
          // 获取执行应用字段
          // let apiFieldInfo = await triggerApi.getApiFiledInfo({fromApis: [{ apiId: fromApiId, name: 'sdf' }], toApiId})

          // 拆分json类型字段（子表单）
          // apiFieldInfo.data.toFieldList = convertJsonFieldTypeToFieldList(apiFieldInfo.data.toFieldList)
          // apiFieldInfo.data.selectFieldList = convertJsonFieldTypeToFieldList(apiFieldInfo.data.selectFieldList)

          this.loading = false
          const actionAppFieldList = {
            // fromFieldList: addSupportProperty(apiFieldInfo.data.fromFieldList || [], 'supportSelect'),
            // selectFieldList: addSupportProperty(apiFieldInfo.data.selectFieldList || [], 'supportSelect'),
            // toFieldList: addSupportProperty(apiFieldInfo.data.toFieldList || [], 'supportInsert'),
          }

          this.nodeConfig = toTreeData(triggerInfo, conditionFieldList, actionAppFieldList)
          this.serverTriggerInfo = triggerInfo
          // console.log(
          //   'this.nodeConfig', JSON.parse(JSON.stringify(this.nodeConfig))
          // )
        } else {
          this.$alert(res?.message || '', this.$t('common.base.tip.confirmTips'), {
            confirmButtonText: this.$t('common.base.makeSure'),
            cancelButtonText: this.$t('common.base.cancel'),
            type: 'error',
          })
        }
      }).finally(()=> this.loading = false)
    } else {
      if(this.getQueryString('apiId')){
        // 从API设置过来的
        let startId = uuid();
        this.nodeConfig = {
          nodeName: this.$t('common.connector.title.trigger'),
          type: 0,
          isStart: true,
          uniqueId: startId,
          id:null,
          parentId: 0,
          getParent:null,
          childNodes: [
            {
              nodeName: this.$t('common.connector.title.trigger'),
              type: 1,
              childNodes: [],
              isTrigger: true,
              uniqueId: uuid(),
              parentId: startId,
              getParent:this.triggerParent,
              data: {
                bizActionCode: '',
                bizActionName: '',
              },
            },
          ],
          data: {
            appId: this.getQueryString('bizTypeId'),
            inside: true,
            name: this.getQueryString('appName'),
            logo: this.getQueryString('logo'),
            bizType: this.getQueryString('bizType'),
            bizTypeId: this.getQueryString('apiId'),
          },
        };
        return
      }
      if(this.getQueryString('bizTypeId')){
        triggerApi.getTriggerFormInfo({
          'bizType': this.getQueryString('bizType'),
          'bizTypeId':this.getQueryString('bizTypeId'),
          'paasAppId':this.getQueryString('paasAppId'),
          'oldActionCode': this.getQueryString('bizActionCode') || ''
        }).then(res=>{
          if(res.status != 0) return this.$message.error(res.message || '')
          if(res.status == 0){
            let { appId, inside, bizType, bizTypeId, bizTypeLogo, bizTypeName, currActionCode} = res.data
            let startId = uuid();
            this.nodeConfig = {
              nodeName: this.$t('common.connector.trigger.startApp'),
              type: 0,
              isStart: true,
              uniqueId: startId,
              id:null,
              parentId: 0,
              getParent:null,
              childNodes: [ ],
              data: {
                appId,
                appBizType: bizType,
                inside,
                name: bizTypeName,
                logo: bizTypeLogo,
                bizActionCode: currActionCode?.bizActionCode || '',
                bizActionName: currActionCode?.bizActionName,
                bizType,
                bizTypeId,
                bizTypeAndId: `${bizType},${bizTypeId}`,
                eventOptionList: [
                  {
                    bizActionCode: currActionCode?.bizActionCode || '',
                    bizActionName: currActionCode?.bizActionName,
                  }
                ]
              },
            };
          }
        })
      }else{

        let startId = uuid();
        this.nodeConfig = {
          nodeName: this.$t('common.connector.title.trigger'),
          type: 0,
          isStart: true,
          uniqueId: startId,
          id:null,
          parentId: 0,
          getParent:null,
          childNodes: [],
          data: {
            appId: '',
            inside: true,
            name: '',
            logo: '',
            bizType: '',
            bizTypeId: '',
          },
        };
      }
    }
  },
  methods: {
    zoomSize(type) {
      if (type == 1) {
        if (this.nowVal == 50) return;
        this.nowVal -= 10;
      } else {
        if (this.nowVal == 300) return;
        this.nowVal += 10;
      }
    },
    getQueryString(name) {
      let reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, 'i');
      let search = window.location.search;
      let r = search.substr(1).match(reg);
      if (r != null) {
        return decodeURIComponent(r[2]);
      }
      return null;
    },
    triggerParent(){
      return this.nodeConfig
    },
    /**
     * @description 新建触发器时打开发起应用的 select 选择
    */
    openStartApplicationSelectForCreate() {

      if (this.isEditTrigger) {
        return
      }

      const startApplicationSelectComponent = findComponentDownward(this, 'search-tree')
      const show = true

      startApplicationSelectComponent?.handleTreeStatus(show)

    },
    /**
     * @description 新建触发器时打开触发器动作的 select 选择
    */
    openTriggerActionSelectForCreate(newNodeConfig, oldNodeConfig) {

      if (this.isEditTrigger) {
        return
      }

      const triggerComponent = findComponentDownward(this, 'trigger')
      triggerComponent?.focus()

    },
    /**
     * @description 新建触发器时打开触发器动作 后添加节点的 的 选择
    */
    openTriggerActionAfterAddNodeForCreate() {

      if (this.isEditTrigger) {
        return
      }

      const addNodeComponents = findComponentsDownward(this, 'add-node')
      // 取倒数第二个 add-node 组件，因为最后一个 add-node 组件是流程结束的节点
      const nextAddNodeComponent = addNodeComponents[addNodeComponents.length - 2]

      nextAddNodeComponent?.openDropdown()

    },
    /**
     * @description 触发器发起应用 select 变化事件
    */
    startAppSelectChangeHandler() {
      this.openTriggerActionSelectForCreate()
    },
    /**
     * @description 触发器触发动作 select 变化事件
    */
    triggleActionSelectChangeHandler() {
      this.openTriggerActionAfterAddNodeForCreate()
    },
    /**
     * @description 触发器执行应用 select 变化事件
    */
    onExecuteApplicationSelectChangeHandler() {
      //
    },
    save(info){
      // TODO: 数据校验
      validateTreeData(this.nodeConfig).then(valid=>{
        if(valid){
          toServeData(cloneDeep(this.nodeConfig), this.serverTriggerInfo).then(data=>{
            // 数据提交的时候 删除消息配置上的channelList和channelList参数
            data.lineList.forEach(item=>{
              const { action, insertFieldOptions, updateFieldOptions, deleteFieldOptions, messageConfigOptions, codeConfigOptions, javaCode, mappingType} = item.executeAction
              if(messageConfigOptions?.isEditMessage) {
                delete messageConfigOptions.isEditMessage
              }
              if(messageConfigOptions?.channelList) {
                delete messageConfigOptions.channelList
              }
              if(messageConfigOptions?.tenantConfig) {
                delete messageConfigOptions.tenantConfig
              }
              if(messageConfigOptions?.systemTemplateParam) {
                let systemTemplateParam = { ...messageConfigOptions.systemTemplateParam }
                let { sysDisplayFieldCheckMap } = systemTemplateParam
                if(sysDisplayFieldCheckMap && sysDisplayFieldCheckMap.length > 0) {
                  sysDisplayFieldCheckMap = sysDisplayFieldCheckMap.filter(field=> field.check)
                }
                systemTemplateParam.sysDisplayFieldCheckMap = sysDisplayFieldCheckMap
                messageConfigOptions.systemTemplateParam = systemTemplateParam
              }
              const isCodeType = mappingType === 'code'
              let fieldOptions = {}
              const node = data.nodeList.find(node=> item.to === node.uniqueId)
              if(action === 'UPDATE') {
                fieldOptions = updateFieldOptions
              } else if(['INSERT', 'SELECT'].includes(action)) {
                fieldOptions = isCodeType ? {
                  insertCode: javaCode
                } : {
                  insert: convertInsertFieldOptionsForServer(insertFieldOptions)
                }
              } else if(action === 'DELETE') {
                fieldOptions = isCodeType ? { deleteCode: javaCode } : deleteFieldOptions
              } else if(action === 'MESSAGE') {
                fieldOptions = messageConfigOptions
              } else if(action === 'CODE') {
                fieldOptions = codeConfigOptions
              }
              if (item.executeAction?.paasNodeId) {
                fieldOptions.paasNodeId = item.executeAction.paasNodeId
              }

              if(node) {
                changeTreeNodeToServerNodeParams(node, action, fieldOptions)
              }
            })

            const startNode = data.nodeList.find(node=> node.isStart)
            if(startNode) changeTreeNodeToServerNodeParams(startNode, 'SELECT', {})

            data.lineList.forEach(item=> {
              delete item.executeAction
            })
            const triggerNodeInfo = this.nodeConfig?.data
            const bizActionCodeArr = (triggerNodeInfo?.bizActionCode || '').split('/')
            const bizActionCode = bizActionCodeArr[bizActionCodeArr.length - 1] || ''
            let timerOptions = triggerNodeInfo.bizActionCode === 'timer' ? triggerNodeInfo?.timerOptions || {} : {}
            let timeOutPlusOptions = triggerNodeInfo.bizActionCode === 'timeOutPlus' ? {
              timeOutType: triggerNodeInfo?.timeOutType,
              rule: triggerNodeInfo?.rule
            } || {} : {}
            // 事件触发可多选
            const eventOptionList = (this.nodeConfig?.data?.eventOptionList || []).map(x => {
              const codeArr = (x.bizActionCode || x.action || '').split('/');
              const action = codeArr[codeArr.length - 1] || '';

              return {
                action,
                paasNodeId: x.paasNodeId,
              }
            });

            delete timerOptions.bizActionCode
            delete timerOptions.bizActionName
            let { paasNodeId, url } = triggerNodeInfo || {}
            const isNotEvent = allowExecuteWay.includes(bizActionCode);

            let triggerInfo = {
              name:info.name,
              remarks:info.description,
              executeWay: {
                way: isNotEvent ? bizActionCode : 'event',
                options: !isNotEvent ? eventOptionList : bizActionCode === 'timer' ? timerOptions : bizActionCode === 'webhook' ? {
                  url
                } : bizActionCode === 'timeOutPlus' ? timeOutPlusOptions : {
                  action: bizActionCode,
                  paasNodeId,
                },
              },
              // bizActionCode:bizActionCodeArr[bizActionCodeArr.length-1] || '',
              // bizActionName:this.nodeConfig.childNodes[0]?.data?.bizActionName||'',
              // paasNodeId:this.nodeConfig.childNodes[0]?.data?.paasNodeId || '',
              ...data
            }
            if(!isArray(triggerInfo.executeWay.options)) {
              triggerInfo.executeWay.options = [triggerInfo.executeWay.options];
            }
            
            if(this.id)triggerInfo.id = this.id;
            if(this.sync) triggerInfo.sync = this.sync === 'true';
            this.$emit('startLoading')
            localStorage.setItem('showApiTriggerTab', false)
            localStorage.setItem('showAuthTriggerTab', false)
            const addOrUpdatePromise = this.id ? triggerApi.updateTriggerV2(triggerInfo) : triggerApi.createTrigger(triggerInfo)
            addOrUpdatePromise.then(res=>{
              if(res.status == 0){
                if(this.id){
                  message.success(this.$t('common.base.tip.modifySuccess'))
                }else{
                  message.success(this.$t('common.base.tip.createSuccess2'))
                }
                // 判断是不是paas节点过来的或者api设置过来的
                const from = this.getQueryString('from')

                const id = window.frameElement.dataset.id;
                const fromId = window.frameElement.getAttribute('fromid');
                // API设置在编辑后刷新需要定位到触发器tab
                if(from === 'api') {
                  localStorage.setItem('showApiTriggerTab', true)
                } else if(from === 'auth') {
                  localStorage.setItem('showAuthTriggerTab', true)
                }
                setTimeout(()=> {
                  this.$platform.closeTab(id)
                  this.$platform.refreshTab(fromId)
                }, 100)

              }else{
                message.error(res.message)
              }
            }).finally(()=>{
              this.$emit('endLoading')
            })
          })
        }
      })
    }
  },
};
</script>
<style lang="scss">
@import './index.scss';
</style>
